/**
 * 
 */
package route;

import graph.NetworkPoint;
import graph.GraphEdge;
import graph.MBR;
import graph.SpatialSearchTreeObject;
import graph.SplitableSegment;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.LineSegment;

//PolyLine shapes are open curves, with no interior.
// The Shape interface says that open curves should be implicitly closed
// for the purposes of insideness testing.  For our purposes, however,
// we define PolyLine shapes to have no interior, and the contains() 
//methods always return false.
/**
 * @author xiaohui
 * 
 */
public class Route {

	private int id;
	// private RouteNode[] routeNodes;
	private NetworkPoint[] routePoints;
	// int[] usages;
	private double score;
	private double length;
	private int numAttractedFacilities;
	// private double xmin, xmax, ymin, ymax;
	static double ratio = 0.001; // length contribution ratio

	// private List<Integer> usage;

	public Route(int id, NetworkPoint[] routePoints, double length, double score) {
		this.id = id;
		// this.usages = usages;
		this.routePoints = routePoints;

		this.length = length;
		this.score = score;
		numAttractedFacilities = 0;

		// computeMinMax();
	}

	// private void computeMinMax() {
	// xmin = Double.MAX_VALUE;
	// xmax = Double.MIN_VALUE;
	// ymax = Double.MIN_VALUE;
	// ymin = Double.MAX_VALUE;
	// for (RouteNode rn : routeNodes) {
	// if (rn.getX() < xmin) {
	// xmin = rn.getX();
	// }
	// if (rn.getX() > xmax) {
	// xmax = rn.getX();
	// }
	// if (rn.getY() < ymin) {
	// ymin = rn.getY();
	// }
	// if (rn.getY() > ymax) {
	// ymax = rn.getY();
	// }
	// }
	// }

	// /**
	// *
	// * @return piece-wise length of a route
	// */
	// private double computeLength() {
	// double length = 0;
	// for (int i = 0; i < routePoints.length - 1; i++) {
	// length += routePoints[i].distance(routePoints[i + 1]);
	// }
	// return length;
	// }

	// private double computeLength() {
	// double length = 0;
	// ELocation lastOne = null;
	// for (int i = mapMatchedElocs.length - 1; i > 0; i--) {
	// if (i > 0
	// && mapMatchedElocs[i - 1].getEdgeId() == mapMatchedElocs[i]
	// .getEdgeId()) {
	// length += mapMatchedElocs[i].getDistFromNode()
	// - mapMatchedElocs[i - 1].getDistFromNode();
	// }
	//
	// }
	// return length;
	// }

	// public Route(int id, RouteNode[] RouteNodes, double score, int usage) {
	// this.id = id;
	// this.routeNodes = RouteNodes;
	// this.score = score;
	// this.usage = usage;
	// }

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @return the score
	 */
	public double getScore() {
		return score;
	}

	// public RouteNode[] getRouteNodes() {
	// return routeNodes;
	// }
	//
	// public int[] getUsages() {
	// return usages;
	// }

	public double getLength() {
		return length;
	}

	public String toString() {
		return "Route " + id + ", l=" + length + ", s=" + score + " "
				+ ", numFs=" + this.numAttractedFacilities + ","
				+ Arrays.toString(routePoints);
	}

	public int getNumAttractedFacilities() {
		return numAttractedFacilities;
	}

	public void setNumAttractedFacilities(int numAttractedFacilities) {
		this.numAttractedFacilities = numAttractedFacilities;
	}

	// @Override
	// public double computeDistanceTo(double[] point) {
	// double minDist = Double.MAX_VALUE;
	// for (int i = 0; i < routeNodes.length - 1; i++) {
	// RouteNode srcNode = routeNodes[i];
	// RouteNode destNode = routeNodes[i + 1];
	// Coordinate p0 = new Coordinate(srcNode.getX(), srcNode.getY());
	// Coordinate p1 = new Coordinate(destNode.getX(), destNode.getY());
	// LineSegment ls = new LineSegment(p0, p1);
	// double dist = ls.distance(new Coordinate(point[0], point[1]));
	// if (dist < minDist) {
	// minDist = dist;
	// }
	// }
	// return minDist;
	// }

	// /**
	// * check pair-wise line segment
	// */
	// @Override
	// public boolean intersects(Object obj) {
	// if (obj instanceof Route) {
	// Route anotherRoute = (Route) obj;
	// RouteNode[] anotherNodes = anotherRoute.routeNodes;
	// boolean intersected = false;
	// for (int i = 0; i < routeNodes.length - 1; i++) {
	// RouteNode srcNode = routeNodes[i];
	// RouteNode destNode = routeNodes[i + 1];
	// Coordinate p0 = new Coordinate(srcNode.getX(), srcNode.getY());
	// Coordinate p1 = new Coordinate(destNode.getX(), destNode.getY());
	// LineSegment ls1 = new LineSegment(p0, p1);
	//
	// for (int j = 0; j < anotherNodes.length - 1; j++) {
	// RouteNode srcNode1 = anotherNodes[j];
	// RouteNode destNode1 = anotherNodes[j + 1];
	// Coordinate p3 = new Coordinate(srcNode1.getX(),
	// srcNode1.getY());
	// Coordinate p4 = new Coordinate(destNode1.getX(),
	// destNode1.getY());
	//
	// LineSegment ls2 = new LineSegment(p3, p4);
	// if (ls1.intersection(ls2) != null) {
	// intersected = true;
	// }
	// }
	// }
	// return intersected;
	// }
	// return false;
	// }
	//
	// @Override
	// public boolean intersects(MBR r) {
	// return this.getMBR().intersects(r);
	// }
	//
	// @Override
	// public boolean isContainedBy(MBR rect) {
	// return rect.contains(this.getMBR());
	// }
	//
	// @Override
	// public boolean isOfSameType(SpatialSearchTreeObject obj) {
	// if (obj instanceof Route) {
	// return true;
	// }
	// return false;
	// }
	//
	// @Override
	// public boolean contains(MBR rect) {
	// return false;
	// }
	//
	// @Override
	// public MBR getMBR() {
	// return new MBR(xmin, ymin, xmax - xmin, ymax - ymin);
	// }
	//
	// public double getXmin() {
	// return xmin;
	// }
	//
	// public void setXmin(double xmin) {
	// this.xmin = xmin;
	// }
	//
	// public double getXmax() {
	// return xmax;
	// }
	//
	// public void setXmax(double xmax) {
	// this.xmax = xmax;
	// }
	//
	// public double getYmin() {
	// return ymin;
	// }
	//
	// public void setYmin(double ymin) {
	// this.ymin = ymin;
	// }
	//
	// public double getYmax() {
	// return ymax;
	// }
	//
	// public void setYmax(double ymax) {
	// this.ymax = ymax;
	// }
	//
	// /**
	// * Test for containment
	// *
	// * @param ss
	// * @return
	// */
	// public boolean contains(SplitableSegment ss) {
	// return this.xmin <= ss.getStartPoint()[0]
	// && this.xmax >= ss.getStartPoint()[1]
	// && this.ymin <= ss.getEndPoint()[0]
	// && this.ymax >= ss.getEndPoint()[1];
	//
	// }

	public NetworkPoint[] getRoutePoints() {
		return routePoints;
	}

	public NetworkPoint getRoutePoint(int index) {
		return routePoints[index];
	}

}
